home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
ai
/
nrlibe32
/
example2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-11-30
|
9KB
|
254 lines
/****************************************************************************/
/* */
/* Example 2 of NRLIB32 library use */
/* */
/* This program is an example of genetic algoritm for xor net training. */
/* A population of nets are tested for xor behavior. Net fitness correspond*/
/* to inverse of mean quadratic error. */
/* After all nets are tested , they are ordered according to their fitness */
/* (first the best or the minimum mean quadratic error). */
/* */
/* This is the first generation ; best 1/5 of population procreate and */
/* replace other nets (total nets is constant) . */
/* On new population we apply a little random mutations to weights. */
/* */
/* In this example, application of genetic algoritm is not a classical */
/* version, because we don't use binary alphabet for genetic string and */
/* we don't apply crossover operator (sexual procreation). */
/* */
/* This algoritm is repeated for more generations , and you can see that */
/* the net behavior improve. */
/* */
/* This algoritm is slower than EBP , but is useful in tasks that need more*/
/* complicated fitness evaluation than exactly answers , like ecological */
/* tasks. */
/* */
/* You must compile this program and link it with NRLIB32.OBJ file. */
/* Memory model is large. */
/* */
/****************************************************************************/
# include "nrlib32.h" /* Library include */
# include <stdio.h>
# include <stdlib.h>
# include <math.h>
# define TU 500 /* Max number of nets */
# define MLIV 2 /* Max layer */
# define NL0 2 /* Layer 0 nodes */
# define NL1 4 /* Layer 1 nodes */
# define NL2 1 /* Layer 2 nodes */
# define NULLL 0L
struct un /* Fitness list */
{
int nr; /* Net number */
float err; /* Mean quadratic error */
} un[TU+1];
/* Buffers for net inputs and output */
float vinp[NL0+1];
float vout[NL2+1];
float verr[NL2+1];
float err[TU+1]; /* Buffers for net quadratic errors */
int tu=100; /* Total default nets */
int tgen=300; /* Total default generations */
int bu; /* Buffer for range of best nets that procreate*/
char filetrain[]="nettrain.dat"; /* Training file */
float frndab(float a,float b);
main(int argc, char *argv[])
{
int i,ge,ta;
long sss;
for (i=1;i<argc;i++)
{
if (strncmp(argv[i],"/tu=",4) == 0) {tu=atoi(argv[i]+4);continue;}
if (strncmp(argv[i],"/tg=",4) == 0) {tgen=atoi(argv[i]+4);continue;}
if (strncmp(argv[i],"/h",2) == 0) {help();exit(0);}
}
if (tu > 500) tu=500;
bu=tu/5; /* Range of selection(1/5 of population)*/
param("fd","0"); /* No verbose */
time(&sss);srand((int)sss); /* Init random seed */
initialize(); /* Create nets */
evolution(); /* Nets life and evolution */
end();
}
initialize()
{
int i,j,nu;
LONG vn[MLIV+1];
char vf[MLIV+1][10], va[MLIV+1][10];
/* Init array for <createallnets> function */
vn[0]=NL0;strcpy(vf[0],"f1");strcpy(va[0],"0");
vn[1]=NL1;strcpy(vf[1],"f5");strcpy(va[1],"0");
vn[2]=NL2;strcpy(vf[2],"f5");strcpy(va[2],"0");
param("ra","-1");param("rb","1"); /* modify default random weigt generation*/
/* Nets creation */
createallnet(tu,MLIV,vn,vf,va);
for (nu=1;nu<=tu;nu++) un[nu].nr=nu; /* Initialize fitness list */
}
evolution()
{
int ge;
for (ge=1;ge<=tgen;ge++) /* Loop for <tgen> generations */
{
netlife() ; /* Test all nets */
errshow(ge); /* Display best performance (min. err) */
procreate(); /* New generation (best selected) */
}
}
netlife()
{
int cv,nu,ret,i,j,stp=0;
float errq,fout[NL2+1];
static FILE *fp;
/* Open trainer file for input values and */
/* reference output values */
if (fp == NULLL)
{
fp = fopen(filetrain,"r");
if (fp == NULLL) {printf("Can't open trainer file \r\n");exit(-1);}
}
/********** Loop for all records of trainer file */
/* each record = 1 life step */
while(fscanf(fp,"%f",&vinp[1]) > 0)
{
/* Input values to <vinp> array */
for (i=2;i<=NL0;i++)
{
ret=fscanf(fp,"%f",&vinp[i]);
if (ret <= 0)
{printf("Error on trainer file \r\n");exit(-1);}
}
/* Reference output values to <fout> array */
for (i=1;i<=NL2;i++)
{
ret=fscanf(fp,"%f",&fout[i]);
if (ret <= 0)
{printf("Error on trainer file \r\n");exit(-1);}
}
stp++; /* one more life step */
/* Apply input to all nets and compute output */
for (nu=1;nu<=tu;nu++)
{
for (i=1;i<=NL2;i++) verr[i]=fout[i]; /*because verr is modified by*/
errq=compute(nu,vinp,vout,verr); /*compute function */
err[nu]=err[nu]+errq;
}
}
/********** end trainer file loop = end life */
rewind(fp);
/* Average quadratic error */
for (nu=1;nu<=tu;nu++) err[nu]=err[nu]/stp;
/* Load fitness list */
for (i=1;i<=tu;i++) {j=un[i].nr;un[i].err=err[j];err[j]=0;}
/* Sort list (first best = lowest error) */
listsort(un,tu);
}
errshow(int ge)
{
printf("Generation %4d Lowest error %7.4f Net %3d \n",
ge,un[1].err,un[1].nr);
}
procreate()
{
int i,j,nu;
LONG in,tc,jc,node;
float weigt;
/* Clone the bests <bu> nets */
for (i=bu+1;i<=tu;i++) copynet(un[rndab(1,bu)].nr,un[i].nr);
/* Now the <tu> nets are represented by only <bu> models*/
/* Apply a little randomic mutation */
for (i=bu+1;i<=tu;i++)
{
nu=un[i].nr;
for (in=1;in<=NL0+NL1+NL2;in++)
{
rnconn(nu,in,&tc);
for (jc=0;jc<tc;jc++) /* note that link <jc> start from 0 */
{rconn(nu,in,jc,&weigt,&node);
weigt=weigt+frndab(-.1,.1);
wwgt(nu,in,jc,weigt); }
}
}
/* Now we have a new generation */
}
end()
{
cancnets();
exit(0);
}
help()
{
printf("\n NET TRAINING WITH GENETIC ALGORITM \n");
printf("\n parameters: ");
printf("\n /tu=.. : total nets (def = 100)");
printf("\n /tg=.. : total generations (def = 300)");
printf("\n ");
}
rndab(int a,int b) /* Integer random value between a and b */
{
float num;
num= rand()&0x7FFF; num=num/MAX_RAND;
return (floor)(num*(b-a)+a+.5);
}
float frndab(float a,float b) /* Float random between a and b */
{
float num;
num= rand()&0x7FFF; num=num/MAX_RAND;
return (num*(b-a)+a);
}
listsort(struct un vet[],int dim) /* Sort in ascendig order of vet[].err*/
{
int c,i,appo2;
float appo1;
for (c=1; c<=dim; c++)
{
for (i=dim;i>c;i--)
{
if (vet[i].err < vet[i-1].err)
{ appo1=vet[i].err; vet[i].err=vet[i-1].err; vet[i-1].err=appo1;
appo2=vet[i].nr; vet[i].nr=vet[i-1].nr; vet[i-1].nr=appo2; }
}
}
}